package top.tenebrous.yzl.chat.service.impl.system;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import top.tenebrous.yzl.basic.constant.Constants;
import top.tenebrous.yzl.basic.constant.ResultCode;
import top.tenebrous.yzl.basic.enums.DeleteStatus;
import top.tenebrous.yzl.basic.model.CtsResult;
import top.tenebrous.yzl.basic.model.YzlChatResult;
import top.tenebrous.yzl.chat.constants.RedisKeyConstants;
import top.tenebrous.yzl.chat.domain.member.MMemUser;
import top.tenebrous.yzl.chat.mapper.member.MMemUserMapper;
import top.tenebrous.yzl.chat.model.*;
import top.tenebrous.yzl.chat.service.system.ISysLoginService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Classname SysLoginServiceImpl
 * @Description TODO
 * @Date 2023/11/29 10:52 PM
 * @Created by zhangya
 */
@Slf4j
@Service
public class SysLoginServiceImpl implements ISysLoginService {

  @Resource
  private MMemUserMapper memUserMapper;

  @Autowired
  private StringRedisTemplate stringRedisTemplate;

  @Override
  public YzlChatResult<SaTokenInfo> login(LoginDTO loginDTO) {
    // 根据用户手机号获取用户信息信息
    MMemUser mMemUser = memUserMapper.selectOne(new LambdaQueryWrapper<MMemUser>()
            .eq(MMemUser::getPhone, loginDTO.getPhone())
            .eq(MMemUser::getIsDelete, DeleteStatus.DELETE_NO.getStatus())
    );
    if (Objects.isNull(mMemUser)) {
      return YzlChatResult.error(500,"用户不存在");
    }
    if (Objects.equals(mMemUser.getUserStatus(), Constants.INT_ONE)) {
      return YzlChatResult.error(ResultCode.C500.code, "当前用户已被禁用");
    }
    // 对用户密码进行加密匹配
    String pw_hash = SaSecureUtil.sha256(loginDTO.getPassword());
    // 校验加密后的密码 是否与数据库中的是否匹配
    // TODO 后续加入次数限制
    if (!pw_hash.equals(mMemUser.getUserPass())) {
      return YzlChatResult.error(ResultCode.C500.code, "密码输入错误");
    }
    // 先下线之前的token
    StpUtil.logout(mMemUser.getId());
    // sa-token 采用sa-token，对用户登录进行托管 该操作会将数据自动提交到redis中
    StpUtil.login(mMemUser.getId());
    // 设置登录用户信息
    MemberLoginInfo loginInfo = MemberLoginInfo.builder()
            .userName(mMemUser.getUserName())
            .id(mMemUser.getId())
            .gender(mMemUser.getGender())
            .city(mMemUser.getCity())
            .imageUrl(mMemUser.getImageUrl())
            .province(mMemUser.getProvince())
            .build();
    StpUtil.getSession().set("loginInfo", loginInfo);

    // TODO 对该账号提供权限及角色
    
    // 获取用户登录后的token信息，并返回给前端
    SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
    stringRedisTemplate.opsForValue().set(String.format(RedisKeyConstants.TOKEN, tokenInfo.getTokenValue()), JSON.toJSONString(loginInfo), tokenInfo.tokenTimeout, TimeUnit.SECONDS);
    return YzlChatResult.success(tokenInfo);
  }

  @Override
  public YzlChatResult<LoginResultDto> getLoginInfo(MemberLoginInfo userInfo) {
    LoginResultDto res = new LoginResultDto();
    try {

      // 加载菜单
//      List<LoginMenuDto> menu = initMenuInfo(token);
      // 获取权限
      res.setPermissions(null);
      // 设置菜单
      res.setMenu(null);
      res.setUserInfo(userInfo);

      log.info("获取登录信息最终返回结果：{}", JSONObject.toJSONString(res));
    } catch (Exception e) {
      log.error("获取用户登录数据异常：{}", e);
      return YzlChatResult.error(500, "获取用户登录数据异常！");
    }
    return YzlChatResult.success(res);
  }

}
